/**
 * babel编译流程
 * 1.parse将源代码编译成AST
 * 2.transform是对AST做增删改
 * 3.generate 是打印 AST 成目标代码并生成 sourcemap
 * 4.babel 中插件的应用顺序是：先 plugin 再 preset，plugin 从左到右，preset 从右到左
 *
 * babel 6
 * 引入preset概念（plugin集合）例如想用es6语法就引用babel-preset-es2015
 * 类似stage0这样的是还没有加入标准的特征如babel-preset-stage-0
 * 存在的问题
 * es 的标准每年都在变，现在的 stage-0 可能很快就 stage-2 了，那 preset 怎么维护，要不要跟着变，用户怎么知道这个 stage-x 都支持什么特性
 * 只能转成 es5，那目标环境支持一些 es6 特性了，那这些转换和 polyfill 岂不是无用功？ 而且还增加了产物的体积。
 * polyfill 手动引入，比较麻烦，有没有更好的方式
 *
 * babel 7
 * 废除了preset-20xx 和 preset-stage-x 的 preset 包，换成了 preset-env默认会支持所有 es 标准的特性，如果没进入标准的，不再封装成 preset，需要手动指定 plugin-proposal-xxx。解决了babel 6 preset经常更新的问题
 * preset-env自动引入了polyfill但并不是默认开启
 *  {
      "presets": [["@babel/preset-env", { // 这样就通过 preset-env 解决了转换了目标环境已经支持的特性的问题
        "targets": "> 0.25%, not dead", // 新增加brwoserslist，babel 会使用 brwoserslist 来把它们转成目标环境具体版本的数据，剩下不支持的就交给perset-env处理。
        "useBuiltIns": "usage",// useBuiltIns 就是使用 polyfill （corejs）的方式，是在入口处全部引入（entry），还是每个文件引入用到的（usage），或者不引入（false）
        "corejs": 3 // corejs 就是 babel 7 所用的 polyfill，需要指定下版本，corejs 3 才支持实例方法（比如 Array.prototype.fill ）的 polyfill
      }]]
    }
    存在的问题
    因为babel插件的执行顺序 @babel/plugin-transform-runtime 是不支持配置 targets 的，因为不知道目标环境支持啥，它只能全部做转换。
 *
 * babel 8
 * 还没发布但是babel 8 会自动引入@babel/polyfills解决babel 7的问题
 */


/**
 * 1.dev环境下会执行
 * 2.生产环境会删除代码
 */

module.exports = ({
  types: t
} /* 将types当成t来使用 */ ) => {
  return {
    visitor: {
      // 遍历ast树修改ast树（下面的函数相当于各种拦截器）
      Identifier(path) {
        // console.log('Identifier', path.node.name) // path.node.name节点的名字
        const parentIsIf = t.isIfStatement(path.parentPath) // 判断父节点是不是if
        const isDebug = path.node.name === "DEBUG"
        if (isDebug && parentIsIf) {
          // 把Identifier转化成string
          const stringNode = t.stringLiteral('DEBUG') // 转化成string类型
          path.replaceWith(stringNode) // 替换node
        }
      },
      StringLiteral(path) { // 遇到类型为字符串的节点
        const parentIsIf = t.isIfStatement(path.parentPath) // 判断父节点是不是if
        const isDebug = path.node.value === "DEBUG"
        if (isDebug && parentIsIf) {
          // 通过node环境变量控制在生产环境下才移除
          if (process.env.BABEL_ENV === 'production') { // 通过cross-env设置全局变量，和webpack的NODE_ENV区分开
            path.parentPath.remove() // 删除节点
          }
        }
      }
    }
  }
}
